package com.yunsc.order.sevice.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.alibaba.fastjson.JSON;
import com.yunsc.common.exception.YunscException;
import com.yunsc.common.utils.DateUtils;
import com.yunsc.common.utils.PageResult;
import com.yunsc.media.service.UploadService;
import com.yunsc.order.dto.OrderExportDTO;
import com.yunsc.order.dto.QueryOrderDTO;
import com.yunsc.order.entity.YunscOrderExportEntity;
import com.yunsc.order.sevice.ExportOrderService;
import com.yunsc.order.sevice.YunscOrderExportService;
import com.yunsc.order.sevice.YunscOrderService;
import com.yunsc.order.vo.OrderDetailVO;
import com.yunsc.order.vo.OrderExportVO;
import com.yunsc.order.vo.OrderGoodsVO;
import com.yunsc.system.entity.YunscStoreUserEntity;
import com.yunsc.system.service.YunscStoreUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static com.yunsc.common.export.ExportUtil.*;
import static com.yunsc.common.utils.DateUtils.convertDateToSeconds;
import static com.yunsc.common.utils.DateUtils.formatDatetime;

/**
 * @version: 1.0
 * @Author: adan
 * @description:
 * @date: 2024-05-29 22:33
 */
@Slf4j
@Service
public class ExportOrderServiceImpl implements ExportOrderService {

    @Resource
    private UploadService uploadService;
    @Resource
    private YunscStoreUserService storeUserService;
    @Resource
    private YunscOrderService orderService;
    @Resource
    private YunscOrderExportService orderExportService;
    @Override
    public void exportOrder(OrderExportDTO params, Integer storeId) {
        String betweenTime = params.getBetweenTime();
        String[] timeArr = betweenTime.split(",");
        String startDate = timeArr[0];
        String endDate = timeArr[1];


        // 得到订单数据
        QueryOrderDTO queryOrderDTO = new QueryOrderDTO();
        BeanUtils.copyProperties(params, queryOrderDTO);
        queryOrderDTO.setBetweenTimeStart(startDate);
        queryOrderDTO.setBetweenTimeEnd(endDate);
        queryOrderDTO.setPageSize(Integer.MAX_VALUE);
        PageResult<OrderDetailVO> pageResult = orderService.queryOrderList(queryOrderDTO, storeId);
        List<OrderDetailVO> dataList = pageResult.getData();
        if (CollectionUtils.isEmpty(dataList)){
            log.info("导出订单数据为空，无需导出");
            throw new YunscException("导出订单数据为空，无需导出");
        }

        // 获取导出的字段
        String columns = params.getColumns();
        Map<String, String[]> resolveFields;
        // 得到需要导出的字段名和excel注解信息
        if (StringUtils.isEmpty(columns)){
            resolveFields = resolveClassFieldNames(OrderExportVO.class);
        }else {
            String[] columnArr = columns.split(",");
            List<String> columnList = Arrays.asList(columnArr);
            resolveFields = resolveFieldNames(OrderExportVO.class, columnList);
        }

        exportOrderExcel(dataList, startDate, endDate,  resolveFields, storeId);

    }


    @Override
    public void exportOrderExcel(List<OrderDetailVO> dataList, String startDate, String endDate,  Map<String, String[]> resolveFields, Integer storeId) {

        // 导出订单数据
        String fileName = "订单数据" + DateUtils.getCurrentDateTime() + ".xlsx";
        String headTitle = "订单数据（"+startDate+"至"+endDate+"）";

        List<OrderExportVO> collect = dataList.stream().map(item -> {
            OrderExportVO orderExportVO = new OrderExportVO();
            BeanUtils.copyProperties(item, orderExportVO);
            orderExportVO.setOrderType(item.getOrderType() == 10 ? "实物订单" : "其他订单");
            List<OrderGoodsVO> goodsVOList = item.getGoods();
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < goodsVOList.size(); i++) {
                stringBuilder.append(i+1).append("、商品名称：").append(goodsVOList.get(i).getGoodsName()).append("\n\n");
                stringBuilder.append("商品规格：").append(getGoodsProps(goodsVOList.get(i).getGoodsProps())).append("\n\n");
                stringBuilder.append("商品数量：").append(goodsVOList.get(i).getTotalNum()).append("\n\n");
                stringBuilder.append("商品总价：").append(goodsVOList.get(i).getTotalPayPrice()).append("\n\n");
            }
            orderExportVO.setGoodsDetail(stringBuilder.toString());
            // 创建时间
            orderExportVO.setCreateTime(formatDatetime(item.getCreateTime()));
            orderExportVO.setUpdatePrice(item.getUpdatePrice() == null ? "0.00" : item.getUpdatePrice().toString());
            // 付款状态(10未付款 20已付款)
            orderExportVO.setPayStatus(item.getPayStatus() == 10 ? "未付款" : "已付款");
            // 付款时间
            orderExportVO.setPayTime(item.getPayTime() == null ? "" : formatDatetime(item.getPayTime()));
            // 配送方式(10快递配送 20门店自提 30无需配送)
            orderExportVO.setDeliveryType(item.getDeliveryType() == 10 ? "快递配送" : item.getDeliveryType() == 20 ? "门店自提" : "无需配送");
            // 订单状态(10待付款 20待发货 30待收货 40待评价 50已完成 60已取消)
            orderExportVO.setOrderStatus(item.getOrderStatus() == 10 ? "待付款" : item.getOrderStatus() == 20 ? "待发货" : item.getOrderStatus() == 30 ? "待收货" : item.getOrderStatus() == 40 ? "待评价" : item.getOrderStatus() == 50 ? "已完成" : "已取消");
            // 发货状态(10未发货 20已发货 30部分发货)
            orderExportVO.setDeliveryStatus(item.getDeliveryStatus() == 10 ? "未发货" : item.getDeliveryStatus() == 20 ? "已发货" : "部分发货");
            // 发货时间
            orderExportVO.setDeliveryTime(item.getDeliveryTime() == null ? "" : formatDatetime(item.getDeliveryTime()));
            // 收货状态(10未收货 20已收货)
            orderExportVO.setReceiptStatus(item.getReceiptStatus() == 10 ? "未收货" : "已收货");
            // 收货时间
            orderExportVO.setReceiptTime(item.getReceiptTime() == null ? "" : formatDatetime(item.getReceiptTime()));
            // 订单是否已结算(0未结算 1已结算)
            orderExportVO.setIsSettled(item.getIsSettled() == 0 ? "未结算" : "已结算");
            // 订单结算时间
            orderExportVO.setSettledTime(item.getSettledTime() == null ? "" : formatDatetime(item.getSettledTime()));
            // 订单是否已评论(0未评论 1已评论)
            orderExportVO.setIsComment(item.getIsComment() == 0 ? "未评论" : "已评论");
            // 订单来源(10普通订单 20砍价订单 30秒杀订单)
            orderExportVO.setOrderSource(item.getOrderSource() == 10 ? "普通订单" : item.getOrderSource() == 20 ? "砍价订单" : item.getOrderSource() == 30 ? "秒杀订单" : "其他");
            // 用户信息
            orderExportVO.setUserInfo(item.getUser().getNickName());
            // 收货人
            orderExportVO.setReceiptName(item.getAddress().getName());
            // 收货人信息
            orderExportVO.setReceiptPhone(item.getAddress().getPhone());
            // 收货地址
            orderExportVO.setReceiptAddress(item.getAddress().getDetail());
            return orderExportVO;
        }).collect(Collectors.toList());

        List<String> fieldNames = resolveFields.values().stream().flatMap(Arrays::stream).collect(Collectors.toList());
        // 拼装表头
        YunscStoreUserEntity storeUser = storeUserService.getById(storeId);
        List<List<String>> setHeadList = setHeadList(fieldNames, headTitle,storeUser.getRealName() );

        // 得到需要导出的字段名
        Set<String> fieldIds = resolveFields.keySet();

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        // String fileNametest = "D:\\download\\测试导出.xlsx";
        // 这里 需要指定写用哪个class去写，然后写到第一个sheet，名字为模板 然后文件流会自动关闭
        EasyExcel.write(outputStream, OrderExportVO.class)
                .sheet("订单清单")
                .includeColumnFieldNames(fieldIds)
                .head(setHeadList)
                // 自适应列宽策略
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                // 自定义表头样式
                .registerWriteHandler(getStyleStrategy())
                .doWrite(collect);

        byte[] fileBytes = outputStream.toByteArray();

        // 上传文件
        String uploadedUrl = uploadService.uploadFileBytes(fileBytes, 0, 10, null, fileName, storeUser.getStoreUserId());

        log.info("导出订单数据成功，文件路径：{}", uploadedUrl);

        YunscOrderExportEntity orderExport = new YunscOrderExportEntity();
        orderExport.setStoreId(storeId);
        orderExport.setFilePath(uploadedUrl);
        orderExport.setStartTime(convertDateToSeconds(startDate));
        orderExport.setEndTime(convertDateToSeconds(endDate));
        // 导出状态(10进行中 20已完成 30失败)
        orderExport.setStatus(20);
        orderExportService.save(orderExport);
    }


    private String getGoodsProps(Object goodsProps) {
        if (goodsProps == null){
            return null;
        }
        List<Map<String, Object>> goodsPropsList = JSON.parseObject(goodsProps.toString(), List.class);
        StringBuilder stringBuilder = new StringBuilder();
        goodsPropsList.forEach(item -> {
            Object groupName = JSON.parseObject(item.get("group").toString(), Map.class).get("name");
            Object groupValue = JSON.parseObject(item.get("value").toString(), Map.class).get("name");
            stringBuilder.append(groupName).append(":").append(groupValue).append("；");
        });

        return stringBuilder.toString();
    }
}
